﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

using Coding4Fun.Cannon.Phone.Accelerometer;
using Coding4Fun.Cannon.Phone.Cannon;

namespace Coding4Fun.Cannon.Phone.Controls
{
	public partial class DriveView : UserControl
	{
		bool IsAccelerating { get; set; } 

		private DrivingMode _drivingMode = DrivingMode.Forward;
		private AccelerometerData _lastReading;
	
		public DriveView()
		{
			// Required to initialize variables
			InitializeComponent();
		}

        void Accelerometer_ReadingChanged(object sender, AccelerometerDataAsyncEventArgs e)
        {            
            Dispatcher.BeginInvoke(() => SaveAccelerometerData(e));
        }

        public void StartAccelerometer()
        {
            //NOTE: Moved from constructor as events would fire almost right away
            App.Accelerometer.ReadingChanged += Accelerometer_ReadingChanged;
            App.Accelerometer.Start(5);
		}

        public void StopAccelerometer()
        {
            App.Accelerometer.ReadingChanged -= Accelerometer_ReadingChanged;
			App.Accelerometer.Stop();
        }

        private void SaveAccelerometerData(AccelerometerDataAsyncEventArgs e)
        {
            _lastReading = e.Data;
            if (IsAccelerating)
                CalculateDrive();
        }

		void ForwardIcon_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
		{
			uxShifter.Value = (int)DrivingMode.Forward;
		}

		void ReverseIcon_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
		{
			uxShifter.Value = (int)DrivingMode.Reverse;
		}

		void Shifter_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			SetMode(Math.Round(e.NewValue) == 1 ? DrivingMode.Forward : DrivingMode.Reverse);
		}

		void SetMode(DrivingMode newmode)
		{
			if (newmode == _drivingMode)
				return;

			_drivingMode = newmode;

			if (_drivingMode == DrivingMode.Forward)
				uxSB_SwitchToForward.Begin();
			else
				uxSB_SwitchToReverse.Begin();
		}

		private void CalculateDrive()
        {
        	if (!IsAccelerating)
				return;

        	Logger.WriteLine("Inside:Accelerate");

        	int leftEngine;
        	int rightEngine;

        	CannonDrive.SetEngineSpeed(out leftEngine, out rightEngine, _drivingMode, _lastReading.Y);

        	Drive(leftEngine, rightEngine);
        }

		private void Drive(int leftEngine, int rightEngine)
        {
			App.Service.Drive(leftEngine, rightEngine); 

			LeftEngine.Text = leftEngine.ToString();
			RightEngine.Text = rightEngine.ToString();
        }

        private void uxGasPedal_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {            
            IsAccelerating = true;
        }


        private void uxGasPedal_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            Logger.WriteLine("Inside:uxGasPedal_ManipulationCompleted ");
			
			IsAccelerating = false;

			Drive(0, 0);
			Drive(0, 0);
        }
	}
}